#include <nitro.h>
#include "phc_struct.h"
#include "phc_beep.h"

/***********************************************************************
これだけ検査で使いたい
***********************************************************************/
static const Note note_decide[] =
{
  { 100, NOTE_TEMPO }, { NOTE_32, NOTE_MI4 }, { NOTE_16, NOTE_RE4 }, { NOTE_1, NOTE_END},
};
/***********************************************************************
***********************************************************************/
static const Note note_cancel[] =
{
  { 180, NOTE_TEMPO }, { NOTE_32, NOTE_SO3 }, { NOTE_32, NOTE_SO2 }, { NOTE_16, NOTE_RE3 }, { NOTE_1, NOTE_END},
};

/***********************************************************************
***********************************************************************/
static const Note note_select[] =
{
  { 240, NOTE_TEMPO }, { NOTE_16, NOTE_FA3 }, { NOTE_1, NOTE_END},
};

/***********************************************************************
***********************************************************************/
static const Note note_success[] =
{
  { 150, NOTE_TEMPO }, { NOTE_4, NOTE_SO3 }, { NOTE_4, NOTE_RE3S }, { NOTE_1, NOTE_END},
};
/***********************************************************************
***********************************************************************/
static const Note note_fail[] =
{
  { 120, NOTE_TEMPO }, { NOTE_32, NOTE_LA3 }, { NOTE_32, NOTE_REST }, { NOTE_8, NOTE_LA3 }, { NOTE_1, NOTE_END},
};
/***********************************************************************
***********************************************************************/
static const Note item_get[] =
{
  { 190, NOTE_TEMPO },

  { NOTE_4, NOTE_DO4 },
  { NOTE_4/3, NOTE_DO4, }, { NOTE_4/3, NOTE_DO4, }, { NOTE_4/3, NOTE_DO4, },
  { NOTE_2/3, NOTE_DO4S, }, { NOTE_2/3, NOTE_DO4S, }, { NOTE_2/3, NOTE_DO4S, },
  { NOTE_2, NOTE_DO4, },

  { NOTE_1, NOTE_END},
};
/***********************************************************************
***********************************************************************/
static const Note note_comget[] =
{
  { 170, NOTE_TEMPO },
#if 1
  { NOTE_8, NOTE_SO3 }, { NOTE_16, NOTE_SO3 }, { NOTE_16, NOTE_SO3 },
  { NOTE_4, NOTE_RE3S }, { NOTE_8, NOTE_SO3S }, { NOTE_16, NOTE_SO3S }, { NOTE_16, NOTE_SO3S },
  { NOTE_8, NOTE_LA4S }, { NOTE_16, NOTE_LA4S }, { NOTE_16, NOTE_LA4S },
#endif
#if 1
  { NOTE_4, NOTE_RE4S|NOTE_SLUR }, { NOTE_8H, NOTE_RE4S },
#else
  { NOTE_4, NOTE_RE4S }, { NOTE_1, NOTE_SLUR}, { NOTE_8H, NOTE_RE4S },
#endif
  { NOTE_1, NOTE_END},
};
/***********************************************************************
***********************************************************************/
static const Note note_pokeget[] =
{
  { 136, NOTE_TEMPO },
  { NOTE_16, NOTE_SO3S }, { NOTE_16, NOTE_SO3S },
  { NOTE_16, NOTE_SO3S }, { NOTE_16, NOTE_SO3S }, { NOTE_16, NOTE_MI3 }, { NOTE_16, NOTE_MI3 },
  { NOTE_16, NOTE_MI3 }, { NOTE_16, NOTE_MI3 }, { NOTE_16, NOTE_SI4 }, { NOTE_16, NOTE_SI4 },
  { NOTE_16, NOTE_SI4 }, { NOTE_16, NOTE_SI4 }, { NOTE_16, NOTE_LA4 }, { NOTE_16, NOTE_LA4 },
  { NOTE_16, NOTE_LA4 }, { NOTE_16, NOTE_LA4 }, { NOTE_2, NOTE_SO3S }, { NOTE_4, NOTE_SO3S },
  { NOTE_1, NOTE_END},
};

/***********************************************************************
***********************************************************************/
static const Note note_dowsing[] =
{
  { 180, NOTE_TEMPO },
  { NOTE_4, NOTE_DO4 }, { NOTE_4, NOTE_DO4 }, { NOTE_4, NOTE_DO4 }, { NOTE_4, NOTE_DO4 }, { NOTE_4, NOTE_DO4 },
  { NOTE_1, NOTE_END},
};
/***********************************************************************
***********************************************************************/
#if 0
static const Note note_comm[] =
{
  { 120, NOTE_TEMPO },
  { NOTE_32, NOTE_RE4S }, { NOTE_32, NOTE_RE3S }, { NOTE_16, NOTE_RE4S },
  { NOTE_32, NOTE_LA4S }, { NOTE_32, NOTE_RE4S }, { NOTE_32, NOTE_LA4S }, { NOTE_32, NOTE_RE4S },
  { NOTE_16, NOTE_RE3S }, { NOTE_32, NOTE_RE4S }, { NOTE_32, NOTE_RE3S },
  { NOTE_32, NOTE_RE4S }, { NOTE_32, NOTE_LA4S }, { NOTE_16, NOTE_RE4S },
  { NOTE_8, NOTE_LA4S },
  { NOTE_1, NOTE_END},
};
#endif
/***********************************************************************
***********************************************************************/
static const Note note_friend[] =
{
  { 220, NOTE_TEMPO },
  { NOTE_8, NOTE_SO3 }, { NOTE_8, NOTE_SO3 },
  { NOTE_8, NOTE_MI3 }, { NOTE_8, NOTE_LA4 },
  { NOTE_8, NOTE_SO3 }, { NOTE_8, NOTE_SI4 },
  { NOTE_4, NOTE_DO4 },
  { NOTE_1, NOTE_END},
};
/***********************************************************************
***********************************************************************/
static const Note note_encount[] =
{
  { 160, NOTE_TEMPO },
  { NOTE_16, NOTE_MI3 }, { NOTE_16, NOTE_FA3 }, { NOTE_16, NOTE_FA3S }, { NOTE_16, NOTE_SO3 },
  { NOTE_16, NOTE_MI3 }, { NOTE_16, NOTE_FA3 }, { NOTE_16, NOTE_FA3S }, { NOTE_16, NOTE_SO3 },
  { NOTE_16, NOTE_MI3 }, { NOTE_16, NOTE_FA3 }, { NOTE_16, NOTE_FA3S }, { NOTE_16, NOTE_SO3 },
  { NOTE_16, NOTE_MI3 }, { NOTE_16, NOTE_FA3 }, { NOTE_16, NOTE_FA3S }, { NOTE_16, NOTE_SO3 },

  { NOTE_16, NOTE_MI3 }, { NOTE_16, NOTE_FA3 }, { NOTE_16, NOTE_FA3S }, { NOTE_16, NOTE_SO3 },
  { NOTE_16, NOTE_MI3 }, { NOTE_16, NOTE_FA3 }, { NOTE_16, NOTE_FA3S }, { NOTE_16, NOTE_SO3 },
  { NOTE_16, NOTE_MI3 }, { NOTE_16, NOTE_FA3 }, { NOTE_16, NOTE_FA3S }, { NOTE_16, NOTE_SO3 },
  { NOTE_16, NOTE_MI3 }, { NOTE_16, NOTE_FA3 }, { NOTE_16, NOTE_FA3S }, { NOTE_16, NOTE_SO3 },
  { NOTE_4, NOTE_SO3 }, { NOTE_1, NOTE_END},
};
/***********************************************************************
***********************************************************************/
static const Note note_attack[] =
{
  { 150, NOTE_TEMPO }, { NOTE_16, NOTE_DO3 }, { NOTE_16, NOTE_SO3 }, { NOTE_1, NOTE_END},
};
/***********************************************************************
***********************************************************************/
static const Note note_avoid[] =
{
  { 240, NOTE_TEMPO }, { NOTE_16, NOTE_DO2 }, { NOTE_8H, NOTE_DO2 }, { NOTE_1, NOTE_END},
};
/***********************************************************************
***********************************************************************/
static const Note note_vital[] =
{
  { 150, NOTE_TEMPO }, { NOTE_32, NOTE_DO4 }, { NOTE_16H, NOTE_SO3 }, { NOTE_1, NOTE_END},
};
/***********************************************************************
重なってる音の下は無視
***********************************************************************/
static const Note note_escape[] =
{
  { 120, NOTE_TEMPO }, { NOTE_32, NOTE_DO3 }, { NOTE_16H, NOTE_DO2 }, { NOTE_16, NOTE_DO2 }, { NOTE_1, NOTE_END},
};
/***********************************************************************
***********************************************************************/
static const Note note_throw[] =
{
  { 120, NOTE_TEMPO }, { NOTE_32, NOTE_SO3 }, { NOTE_32, NOTE_DO3 }, { NOTE_32, NOTE_LA3 }, { NOTE_32, NOTE_SO2 },
  { NOTE_32, NOTE_FA2 }, { NOTE_32, NOTE_MI2 }, { NOTE_32, NOTE_RE2 }, { NOTE_32, NOTE_DO2 }, { NOTE_1, NOTE_END},
};
/***********************************************************************
***********************************************************************/
static const Note * const note_tbl[] =
{
  note_decide, note_cancel, note_select, note_success, note_fail,
  item_get, note_comget, note_pokeget,

  note_dowsing, note_friend, // 通信・友達と通信
  note_encount, note_attack, note_avoid, note_vital,
  note_escape, note_throw,
};
/***********************************************************************
***********************************************************************/
static const u8 size_tbl[] =
{
  sizeof(note_decide), sizeof(note_cancel), sizeof(note_select), sizeof(note_success), sizeof(note_fail),
  sizeof(item_get), sizeof(note_comget), sizeof(note_pokeget),

  sizeof(note_dowsing), sizeof(note_friend), // 通信・友達と通信
  sizeof(note_encount), sizeof(note_attack), sizeof(note_avoid), sizeof(note_vital),
  sizeof(note_escape), sizeof(note_throw),
};
/***********************************************************************
***********************************************************************/
extern void print_sound(void);
extern void print_sound(void)
{
  u32 size = 0;

  OS_Printf("サウンドデータサイズ %d\n", sizeof(note_decide)); size += sizeof(note_decide);
  OS_Printf("サウンドデータサイズ %d\n", sizeof(note_cancel)); size += sizeof(note_cancel);
  OS_Printf("サウンドデータサイズ %d\n", sizeof(note_select)); size += sizeof(note_select);
  OS_Printf("サウンドデータサイズ %d\n", sizeof(note_success)); size += sizeof(note_success);
  OS_Printf("サウンドデータサイズ %d\n", sizeof(note_fail)); size += sizeof(note_fail);

  OS_Printf("サウンドデータサイズ %d\n", sizeof(item_get)); size += sizeof(item_get);
  OS_Printf("サウンドデータサイズ %d\n", sizeof(note_comget)); size += sizeof(note_comget);
  OS_Printf("サウンドデータサイズ %d\n", sizeof(note_pokeget)); size += sizeof(note_pokeget);
  OS_Printf("サウンドデータサイズ %d\n", sizeof(note_dowsing)); size += sizeof(note_dowsing);
  //OS_Printf("サウンドデータサイズ %d\n", sizeof(note_comm)); size += sizeof(note_comm);
  OS_Printf("サウンドデータサイズ %d\n", sizeof(note_friend)); size += sizeof(note_friend);
  OS_Printf("サウンドデータサイズ %d\n", sizeof(note_encount)); size += sizeof(note_encount);
  OS_Printf("サウンドデータサイズ %d\n", sizeof(note_attack)); size += sizeof(note_attack);
  OS_Printf("サウンドデータサイズ %d\n", sizeof(note_avoid)); size += sizeof(note_avoid);
  OS_Printf("サウンドデータサイズ %d\n", sizeof(note_vital)); size += sizeof(note_vital);
  OS_Printf("サウンドデータサイズ %d\n", sizeof(note_escape)); size += sizeof(note_escape);
  OS_Printf("サウンドデータサイズ %d\n", sizeof(note_throw)); size += sizeof(note_throw);
  OS_Printf("サウンドデータサイズ トータル %d\n", size);
}
/***********************************************************************
サウンドデータの合計は 最大 448 バイト(224ノート)
１曲の最大は192 バイト (96ノート)
***********************************************************************/
extern void setup_sound(PHCSoundData *p);
extern void setup_sound(PHCSoundData *p)
{
  int idx;
  u16 offset = 0;
  PHCSoundHeader *pHeader;

  for(idx=0;idx<16;idx++){
	pHeader = &p->header[idx];
	pHeader->adrs = offset;
	pHeader->size = size_tbl[idx]; // バイト数なので注意(note 数ではない)
	{
	  u8 sum;
	  int j;
	  const Note *note;

	  sum = 0;
	  note = note_tbl[idx];
	  for(j=0;j<pHeader->size/sizeof(Note);j++){ sum += (note+j)->count; sum += (note+j)->scale; }
	  pHeader->sum = sum;
	}
	MI_CpuCopy8(note_tbl[idx], &p->data[offset], pHeader->size);
	offset += pHeader->size;
  }
}